/*
 * Copyright © 2004-2014 chenYuan. All rights reserved.
 * @Website:wwww.jspx.net
 * @Mail:39793751@qq.com
 * @author: chenYuan , 陈原
 * @License: Jspx.net Framework Code is open source (LGPL)，Jspx.net Framework 使用LGPL 开源授权协议发布。
 * @jvm:jdk1.6+  x86/amd64
 *
 */
package com.seeyon.apps.ext.kingdee.util;




import java.io.*;

import java.lang.reflect.Method;


import java.util.*;


/**
 * Created by IntelliJ IDEA.
 * User:chenYuan (mail:39793751@qq.com)
 * Date: 2007-1-7
 * Time: 19:04:35
 * com.jspx.utils.BeanUtil
 */
public class BeanUtil {


    private BeanUtil() {

    }



    /**
     * @param object    bean对象
     * @param name      方法名称
     * @param parameter 参数列表
     * @param jump      跳过不满足条件的方法,并且不会报错
     * @return 返回对象
     * @throws NoSuchMethodException 方法不能找到异常
     */
    public static Object getProperty(Object object, String name, Object[] parameter, boolean jump) throws NoSuchMethodException {
        if (!StringUtil.hasLength(name)) return null;
        if (object == null || ClassUtil.isStandardProperty(object.getClass())) {
            return object;
        }
        if (object instanceof Map && parameter == null) {
            Map map = (Map) object;
            return map.get(name);
        }
        Method[] methods = ClassUtil.getDeclaredMethods(object.getClass());
        Method testMethod = null;
        for (Method method : methods) {
            if (method.getGenericReturnType().equals(Void.TYPE)) continue;
            if (method.getName().equals(name) || method.getName().equals(ClassUtil.methodName_get + StringUtil.capitalize(name)) || method.getName().equals(ClassUtil.methodName_is + StringUtil.capitalize(name))) {
                //如果parameter == ArrayUtil.NULL 表示只起无参数的函数
                int iParam = method.getGenericParameterTypes().length;
                if (parameter != ArrayUtil.NULL && parameter.length == iParam || parameter == ArrayUtil.NULL && iParam == 0) {
                    testMethod = method;
                    break;
                }
            }
        }
        if (testMethod == null && jump) return null;
        if (testMethod == null) {
            throw new NoSuchMethodException(object.getClass().getName() + " method not find " + name);
        }
        try {
            if (testMethod.getParameterTypes().length == 0)
                return testMethod.invoke(object);
            else
                return testMethod.invoke(object, parameter);
        } catch (Exception e) {
            e.printStackTrace();
         }
        return null;
    }

    /**
     * 拷贝属性,
     *
     * @param getObj 得到属性的bean
     * @param copyTo 源bean
     */
    public static void copySimpleProperty(Object getObj, Object copyTo) {
        Method[] methodsGet = ClassUtil.getDeclaredMethods(getObj.getClass());
        Method[] methodsSet = ClassUtil.getDeclaredMethods(copyTo.getClass());
        for (Method setMethod : methodsSet) {
            if (setMethod.getName().startsWith(ClassUtil.methodName_set)) continue;
            if (setMethod.getGenericParameterTypes().length > 0) continue;
            try {
                for (Method method : methodsGet) {
                    if (!method.getName().startsWith(ClassUtil.methodName_set)) continue;
                    if (method.getName().substring(3).equals(setMethod.getName().substring(3)) && (setMethod.getName().startsWith(ClassUtil.methodName_get) || setMethod.getName().startsWith(ClassUtil.methodName_is))) {
                        method.invoke(getObj, setMethod.invoke(copyTo));
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * @param f1 方法数组1
     * @param f2 方法数组2
     * @return 合并两个方法数组
     */
    public static Method[] joinMethodArray(Method[] f1, Method[] f2) {
        if (f1 == null) return f2;
        if (f2 == null) return f1;
        Method[] result = new Method[f1.length + f2.length];
        for (int i = 0; i < result.length; i++) {
            if (i < f1.length)
                result[i] = f1[i];
            else
                result[i] = f2[i - f1.length];
        }
        return result;
    }


    public static Method[] appendMethodArray(Method[] f1, Method f2) {
        if (f1 == null && f2 == null) return null;
        if (f2 == null) return f1;
        if (f1 == null) {
            Method[] result = new Method[1];
            result[0] = f2;
            return result;
        }
        Method[] result = new Method[f1.length + 1];
        System.arraycopy(f1, 0, result, 0, f1.length);
        result[f1.length] = f2;
        return result;
    }


    /**
     * @param xmlFile xml文件名称
     * @return XML文件转换为Bean
     * @throws IOException 读取错误
     */
    public static Object getObjectForXml(File xmlFile) throws IOException {
        if (!xmlFile.isFile()) return null;
        java.beans.XMLDecoder decoder = new java.beans.XMLDecoder(new FileInputStream(xmlFile));
        Object beanObject = decoder.readObject();
        decoder.close();
        return beanObject;
    }



    /**
     * @param object bean对象
     * @param string 调用一个方法
     * @param args   参数
     * @throws Exception 运行错误
     */
    public static Object invoke(Object object, String string, Object... args) throws Exception {

        if (object == null || string == null) return null;
        if (args == null) {
            Method method = object.getClass().getMethod(string);
            if (method != null) method.invoke(object);
        } else {
            java.beans.Expression expr = new java.beans.Expression(object, string, args);
            expr.execute();
            return expr.getValue();
        }
        return null;
    }

    /**
     * @param o 对象
     * @return 判断是否对象为一个集合，列表 类型
     */
    public static boolean isArraySet(Object o)
    {
        return  o!=null&&(o.getClass().isArray() || o instanceof Collection || o instanceof Map);
    }



}